#include "equal.hpp"

void		Equal::solve()
{
  if (this->_state == UNDEFINED)
    {
      AObject*					elm;
      unsigned int				taille = this->_cond.size();

      for (unsigned int i = 0; i < taille; ++i)
	{
	  elm = this->_cond.front();
	  this->_cond.pop();
	  elm->solve();
	  this->_state = elm->getState();
	  this->_cond.push(elm);
	}
      if (taille > 1)
	this->_state = UNDEFINED;
      else if (taille == 0) // cas dínitialisation de facts
	this->_state = TRUE;
    }
}

bool		Equal::behaviour(LinkChain lk, LinkChainIterator lk_it,
				 LinkChainIterator prev, LinkChainIterator next)
{ // linker equal en dernier
  LinkChainIterator		checker = next;

  if (prev != lk->end() && next != lk->end())
    {
      if ((++checker) != lk->end())
	return false;
      checker = prev;
      if ((--checker) != lk->end())
	return false;

      bool				prevIsFact = false;
      bool				nextIsFact = false;

      if (((prev->second).first)->getType() == FACT)
	prevIsFact = true;
      if (((next->second).first)->getType() == FACT)
	nextIsFact = true;

      if (!prevIsFact && !nextIsFact)
	return false;
      if ((prevIsFact && nextIsFact) || (!prevIsFact && nextIsFact))
	((next->second).first)->addObject((prev->second).first);
      if (prevIsFact && !nextIsFact)
	((prev->second).first)->addObject((next->second).first);
      ((prev->second).first)->getRequiredLinks(lk, prev, lk_it);
      ((next->second).first)->getRequiredLinks(lk, next, lk_it);
      ((lk_it->second).first)->addObject((prev->second).first);
      ((lk_it->second).first)->addObject((next->second).first);
      return true;
    }
  if (next != lk->end()) // Cas du =VAR
    {
      if ((++checker) != lk->end())
	{
	  if (((next->second).first)->getType() != NOT
	      || ((checker->second).first)->getType() != FACT)
	    return false;
	  else // Cas spécial du =!VAR
	    {
	      ((checker->second).first)->addObject((next->second).first);
	      ((next->second).first)->addObject((lk_it->second).first);
	      ((checker->second).first)->getRequiredLinks(lk, next, lk_it);
	      // Set du flag de not à true pour signaler son linkage
	      // mais sans passer par getRequiredLinks pour lier correctement
	      (checker->second).second = true;
	    }
	}
      // Cas du =a+b par exemple ou encore du =a-b+c-!d
      if (((next->second).first)->getType() != FACT
	  && ((next->second).first)->getType() != NOT)
	{
	  std::cout << "This type of equation is not supported.\n";
	  return false;
	}
      ((next->second).first)->addObject((lk_it->second).first);
      ((next->second).first)->getRequiredLinks(lk, next, lk_it);
      return true;
    }
  return false;
}
